package com.xlongwei.todays.controller;

import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.stream.Collectors;
import org.noear.solon.Utils;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Post;
import org.noear.solon.core.handle.Result;
import org.noear.solon.validation.annotation.Min;
import org.noear.solon.validation.annotation.NotNull;
import org.noear.solon.validation.annotation.Pattern;
import org.noear.solon.validation.annotation.Valid;
import org.noear.solon.validation.annotation.Validated;
import com.xlongwei.todays.config.CronUtils;
import com.xlongwei.todays.dao.ExtraDao;
import com.xlongwei.todays.dao.MydoDao;
import com.xlongwei.todays.dao.TodoDao;
import com.xlongwei.todays.model.Mydo;
import com.xlongwei.todays.model.Todo;
import com.xlongwei.todays.view.MydoQuery;
import cn.dev33.satoken.annotation.SaCheckLogin;
import lombok.extern.slf4j.Slf4j;

@Valid
@Slf4j
@Controller
@SaCheckLogin
@Mapping("mydo")
public class MydoController {
    @Inject
    MydoDao mydoDao;
    @Inject
    TodoDao todoDao;
    @Inject
    ExtraDao extraDao;

    @Get
    @Post
    @Mapping("todo")
    public Result<?> todo(@NotNull @Min(1) Integer todoid, @Pattern("[012]") String status) {
        Integer userid = UserController.userid();
        Mydo row = mydoDao.findByUseridAndTodoid(userid, todoid);
        if (row == null) {
            row = new Mydo();
            row.setUserid(userid);
            row.setTodoid(todoid);
            Todo todo = todoDao.retrieve(todoid);
            if (todo == null || "0".equals(todo.getStatus())) {
                return Result.failure();
            }
            LocalDate today = LocalDate.now();
            ZonedDateTime start = CronUtils.next(todo.getCron(), today);
            row.setToday(today); // 如果是未来的日期执行，则先加入今天待办（我的待办马上可见），手动点完成（等到了目标日期，再自动变为待办）
            row.setStart(start.toLocalTime());
            Integer mydoid = mydoDao.create(row);
            row.setMydoid(mydoid);
        } else if (Utils.isBlank(status) || !status.equals(row.getStatus())) {
            status = Utils.isBlank(status) ? "0".equals(row.getStatus()) ? "1" : "0" : status;
            row.setStatus(status);
            mydoDao.update(row);
        }
        return Result.succeed(row);
    }

    @Post
    @Mapping("list")
    public Result<?> list(@Validated MydoQuery query) {
        query.setUserid(UserController.isAdmin() ? query.getUserid() : UserController.userid());
        List<Mydo> list = null;
        if (query.getToday() != null && query.getToday().isAfter(LocalDate.now())) {
            MydoQuery newQuery = new MydoQuery();
            newQuery.setUserid(query.getUserid());
            list = mydoDao.list(newQuery).stream().filter(row -> {
                if (row == null || "0".equals(row.getStatus())) {
                    return false;// 我的待办：停用
                }
                Todo todo = todoDao.retrieve(row.getTodoid());
                if (todo == null || "0".equals(todo.getStatus())) {
                    return false;// 公共待办：停用
                }
                LocalDate today = query.getToday();
                ZonedDateTime start = CronUtils.next(todo.getCron(), today);
                boolean valid = today.equals(start.toLocalDate());// 当天待办
                boolean next = !valid && "1".equals(todo.getNext()) && "1".equals(row.getStatus());// 顺延待办
                if (valid || next) {
                    row.setToday(today);
                    row.setStart(start.toLocalTime());
                    row.setStatus("1");
                    return true;
                }
                return false;
            }).collect(Collectors.toList());
        } else {
            list = mydoDao.list(query);
        }
        for (Mydo item : list) {
            Todo todo = todoDao.retrieve(item.getTodoid());
            item.setTitle(todo.getTitle());
        }
        return Result.succeed(list);
    }
}
